home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / dev / lang / BCPL4Amiga.lha / tripos / bcpl.doc next >
Text File  |  1988-12-06  |  11KB  |  258 lines

  1.                               BCPL
  2.  
  3. Author: Bill Kinnersley
  4. Date: Mar 12, 1988
  5. Mail: Physics Dept.
  6.       Montana State University
  7.       Bozeman, MT 59717
  8. BITNET: iphwk@mtsunix1
  9. INTERNET: iphwk%mtsunix1.bitnet@cunyvm.cuny.edu
  10. UUCP: ...psuvax1!mtsunix1.bitnet!iphwk
  11.  
  12.  
  13. TRIPOS
  14.  
  15.         AmigaDOS is a port of the TRIPOS operating system developed at
  16. Cambridge University.  From the beginning, Unix and C were meant for
  17. each other. The same thing goes for BCPL and TRIPOS.
  18.  
  19.         On the one hand, TRIPOS was written in a high level language
  20. (BCPL) to provide easy portability from one hardware to another.  A
  21. TRIPOS port requires only the construction of a native kernel to provide
  22. process management and message passing--exactly the services handled on
  23. the Amiga by Exec.  On the other hand, BCPL requires extensive run-time
  24. support that TRIPOS is designed to offer.
  25.  
  26.         In fact the coupling between system and application is even
  27. stronger in TRIPOS than in Unix.  A TRIPOS application program is like a
  28. subroutine of the operating system.  It requires shared access to system
  29. variables (the Global Vector) and resident system libraries.  As a result,
  30. BCPL programs tend to be smaller than C programs.
  31.  
  32.         TRIPOS was never designed to run on mainframes, nor on single
  33. user micros.  From the beginning it was intended to run a network of
  34. workstations.   The target was a collection of small memory, small disk
  35. capacity machines in a network environment.  Multitasking and message
  36. passing are clearly an essential feature of such an environment.
  37. Presumably the hooks for networking are still present in AmigaDOS...
  38.  
  39.  
  40. BCPL
  41.  
  42.         BCPL itself is an ancestor of C and is actually a somewhat lower
  43. level language.  (A sample BCPL program is given in the ROM KernelManual,
  44. Appendix G.)  References to BCPL and TRIPOS are:
  45.  
  46.         Richards, Martin, "TRIPOS--A Portable Operating System
  47.                 for Mini-computers",
  48.                 Software Practice and Experience, 9, 513-526 (1979)
  49.  
  50.         Richards, Martin, "BCPL--the language and its compiler"
  51.                 Cambridge University Press, 1979
  52.                 ISBN 0-521-21965-5   QA76.73 B17 R5
  53.                 Emery, Glyn, "BCPL and C", Blackwell, 1986
  54.                 ISBN 0-632-01607-8   QA76.73 B38 E44
  55.  
  56.         Moody, Ken, "A Coroutine Mechanism for BCPL",
  57.                 Software Practice and Experience, 10, 765 (1980)
  58.  
  59.  
  60. BPTRS
  61.  
  62.           BCPL is a typeless language--every data item takes up the
  63. same amount of storage.  In the 68000 family, pointers are 32 bits.
  64. Hence Amiga TRIPOS is forced to store all data in 32 bit longwords.
  65. Unfortunately, 68000 memory is not longword addressable.  Assembly
  66. expressions like 10(A0,D1) calculate an effective address assuming
  67. that the offsets 10 and D1 are measured in bytes.  This leads to the
  68. need for a distinction between APTRs which are byte addresses, and
  69. BPTRs which are longword addresses.  BPTR = APTR/4, and BPTRs can only
  70. point to locations which are longword aligned.
  71.         (Strings are the only exception to the uniform size rule.  BCPL
  72. strings are packed, four characters to a longword.)
  73.  
  74.  
  75. MULTITASKING
  76.  
  77.         The main AmigaDOS facility for multitasking is the CLI.  CLI's
  78. are kept in a fixed array, so there is a maximum number of CLI's allowed
  79. at any time.  Every BCPL program must be launched from its own CLI.
  80.  
  81.         When a CLI executes a command, it loads the program with LoadSeg
  82. and calls it as a subroutine (not a coroutine as claimed by the AmigaDOS
  83. manual).  It does not create a separate process.  Thus the command
  84. inherits all of the CLI's existing environment: the Task, the Process,
  85. the Input and Output file handles, etc.  When the program returns, the
  86. CLI is there to take care of the cleanup chores.  CLI's may be created
  87. in two ways:
  88.  
  89.         NewCLI creates an interactive CLI.  A new window is created,
  90. along with a new instance of the CON: device.  The default Input and
  91. Output file handles refer to this device.  Interactive CLI's are
  92. destroyed by EndCLI merely by pushing them into the background.  A
  93. background CLI with nothing to do automatically commits suicide.
  94.  
  95.         RUN creates a CLI in the background that executes a given
  96. command and then terminates.  The Input handle is a fake one containing
  97. the command in its input buffer.  The Output handle is shared with
  98. that of the creator.
  99.  
  100.         An AmigaDOS Process may spawn an unlimited number of children
  101. using CreateProc.  (This is what WorkBench does.)  A process created in
  102. this manner automatically starts execution at once, but typically its
  103. first few lines of code causes it wait at the Process DOSPort for a
  104. startup message.  It then continues execution and replies to the message
  105. when done.  This approach is necessary because someone else needs to do
  106. the unloading: either the parent, the WorkBench, or a CLI.
  107.         LoadWB creates a child process, WorkBench, but exits without
  108. waiting for a reply.  As a result WorkBench cannot terminate.
  109.  
  110.  
  111. INITIAL ENVIRONMENT
  112.  
  113.         Upon entry to any BCPL routine, the register contents are as
  114. follows:
  115.  
  116.         d0 - amount of global area currently in use
  117.         d1-d4 - up to 4 parameters.  Further parameters can be passed on
  118.                 the stack (see below).
  119.         d5-d7 - unused
  120.         a0 - base of system address space - always 0.
  121.                 RAM addresses are computed as offsets from a0
  122.         a1 - base of the current BCPL stack frame
  123.         a2 - pointer to the BCPL Global Vector
  124.         a3 - return address of the caller
  125.         a4 - entry address
  126.         a5 - pointer to a "caller" service routine
  127.         a6 - pointer to a "returner" service routine
  128.         a7 - stack for temporaries
  129.  
  130.         This register environment is available to any application
  131. program.  However if you're programming in C, the startup code supplied
  132. by your linker generally ignores the initial register contents and
  133. eventually they get overwritten.
  134.  
  135. The parameters passed by the CLI to an application are:
  136.         d0 - length of command line
  137.         a0 - APTR to command line
  138. The command itself may be found in the CLI->cli_Command field.  Two items
  139. are available on the stack: pointers to the top and the bottom of the
  140. stack that was allocated.
  141.  
  142.  
  143. STACKS AND CALLS
  144.  
  145.         The a7 stack is rarely used by AmigaDOS, except for interfacing
  146. calls to Exec which must be C-like.  Normal BCPL calls use the a1 stack.
  147. It is organized by frames of local variables, growing toward higher RAM
  148. addresses.
  149.  
  150.         In C the caller pushes parameters on the stack in reverse order,
  151. then does the call.  The callee pushes its own locals on the stack as
  152. needed and restores the original stack pointer when done.  The caller
  153. then pops the parameters off.  More specifically, C uses the 68000 LINK
  154. and UNLK instructions to maintain a stack pointer (SP) and a frame
  155. pointer (FP).  Upon entry to a subroutine:
  156.  
  157.           SP--->Nth local
  158.                 ...
  159.                 1st local
  160.           FP--->old FP
  161.                 return address
  162.                 2nd param
  163.                 ...
  164.  
  165.         In BCPL, parameters and locals are not pushed.  There is a frame
  166. pointer, a1, but no stack pointer.  Instead the compiler maintains a
  167. "current size".  The caller puts his parameters in d1-d4, his current
  168. size in d0, the subroutine address in a4, and then jsr's to (a5).
  169.         The (a5) entry routine increments a1 by d0.  It pops the return
  170. address off the a7 stack into a3, saves a1, a3, and a4 in locations just
  171. BELOW a1, saves d1-d4 just ABOVE a1 (all without changing a1), and then
  172. jumps to (a4).  Upon entry to a subroutine:
  173.  
  174.                 old a1
  175.                 return address
  176.                 entry address
  177.           a1--->1st param
  178.                 2nd param
  179.                 ...
  180.  
  181. (Note that BCPL frames grow toward higher memory instead of lower.)  The
  182. (a6) exit routine restores a1, a3, and a4, and jumps to (a3).
  183.  
  184.         A BCPL routine must therefore preserve a0, a1, a2, a5, a6 and a7.
  185. Results are typically returned in d1 and/or a1.
  186.  
  187.         For example, suppose your last global is at 100(a1).  You must
  188. call a subroutine with d0 = 110.  The (a5) routine will save registers
  189. in 104, 108, and 10c, and put the first four parameters at 110, 114, 118,
  190. and 11c.  The called routine (using the new a1) will find them at (a1),
  191. 4(a1), 8(a1), and c(a1).  If you want to pass a 5th parameter, you must
  192. put it ahead of time at 120(a1).  The called routine will find it at 10(a1).
  193.  
  194.         BCPL variables are either global or local.  Global variables are
  195. located in the Global Vector and are visible to all modules.  They are
  196. referenced by an offset from a2.
  197.         In C, the linker combines the globals declared by various program
  198. modules and arranges them in the common area.  BCPL is not linked!  The
  199. BCPL programmer must handle these details himself, declaring explicitly
  200. where each global is to be located in the Global Vector.
  201.         Blocks may be nested, but locals declared in surrounding blocks
  202. are not visible, i.e. nonlocal variables may not be referenced.
  203.  
  204.  
  205. SEGMENTS
  206.  
  207.         A program exists on the disk in sections called hunks.  When the
  208. program is loaded, the hunks are separately relocated as segments, and
  209. these are linked together with headers to form a SegList.  Process
  210. creation combines the program's SegList with several system SegLists to
  211. make up a SegArray.  Execution begins at the beginning of the first
  212. SegList, which is system startup code.  Entries in the SegArray are
  213. allowed to be missing (0), and that is probably the reason for using
  214. an array: to allow easy addition and deletion of chunks of code.
  215.  
  216.         For example, if a program is launched from the CLI, the SegArray
  217. looks like (4/sys1/sys2/sys3/0/prog).  If the program is RUN, theSegArray
  218. will be (4/sys1/sys2/0/sys4/prog).  If the program is CreateProc'ed, the
  219. array is only (2/sys1/sys2).
  220.  
  221.  
  222. MODULE STRUCTURE
  223.  
  224. A BCPL module has the following structure:
  225.  
  226.         dc.l    size    ;module size in longwords
  227.         dc.w    0       ;pad
  228.         dc.b    '09'    ;version
  229.         dc.b    name    ;name of the module as a BSTR
  230.         Any number of BCPL subroutines
  231.         ...
  232.         Table of Global definitions
  233.         dc.l    maxGV   ;GV size the module will need.
  234.  
  235.         Each subroutine may be preceded by a BSTR label.  The main entry
  236. is always labeled "start  ".  If the subroutine uses local constants such
  237. as strings, these immediately follow the code.
  238.  
  239.         The definition table is used to place public entry points into
  240. the GV.  This is done by the startup code, specifically the library
  241. function installseg().  The table consists of pairs:
  242.  
  243.         (offset into the module in bytes, offset into the GV in longwords).
  244.  
  245. The table runs in reverse order, and is terminated with a 0.  For example,
  246. if the module ends with
  247.  
  248.         dc.l    0, 1,24, 85,504, 88
  249.  
  250. it means there are two entries to be installed: offset 24 at GV:1 and
  251. offset 504 at GV:85.  The last number, 88, is the GV size requested.
  252.  
  253.         All BCPL programs that can be called from the command line are
  254. composed of two hunks.  The first hunk is common startup code that makes
  255. a private copy of the system GV before installing the program's globals.
  256. The purpose is to insure that AmigaDOS commands are reentrant.  Global
  257. variables installed by one instance will not overwrite those of another.
  258.